home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Technology Seed / ADC Seed CD - July 1999.toast / Carbon SDK 1.0d10c3 / Sample Code / SimpleText / NavigationServicesSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-04  |  8.0 KB  |  339 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        NavigationServicesSupport.c
  3.  
  4.     Contains:    Code to support Navigation Services in SimpleText
  5.  
  6.     Version:    1.0
  7.  
  8.     Copyright:    © 1997-1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                Yan Arrouye
  13.  
  14.         Other Contact:        Yan Arrouye
  15.  
  16.         Technology:            OS Technologies
  17.  
  18.     Writers:
  19.  
  20.         (KLM)    Keith Mortensen
  21.         (Yan)    Yan Arrouye
  22.  
  23.     Change History (most recent first):
  24.  
  25.          <2>     1/13/98    ted        New drop from nav services team
  26.         <24>      1/5/98    KLM        fixed messed up header
  27.         <23>      1/5/98    KLM        added #include <Processes.h>
  28.         <22>    12/23/97    KLM        updates: now using kNav/Nav
  29.         <21>     11/5/97    KLM        App name in window title
  30.         <20>     11/4/97    KLM        App name in dialog titles
  31.         <19>    10/20/97    KLM        more a6 interface changes
  32.         <18>    10/13/97    KLM        a6 interface changes
  33.         <17>    /19/1997    Yan        Mixed mode support
  34.         <15>     5/23/97    sjf 
  35.         <14>     5/15/97    Yan        Updated for new API
  36.         <13>     5/08/97    KLM        Fixed NewOpenHandle bug, it was never creating a open rsrc.
  37.         <12>     5/08/97    Yan        Use isStationery flag
  38.         <11>     4/21/97    Yan        
  39.         <10>     4/21/97    Yan        NavGetDefaultDialogsOptions really
  40.          <9>     4/21/97    Yan        Use new NavSetDefaultDialogsOptions
  41.          <8>     4/21/97    Yan        Implemented isStationery in save
  42.          <7>     4/21/97    Yan        Updated for latest include
  43.          <6>     4/18/97    Yan        Rev'ed for new API
  44.          <5>     4/14/97    Yan        Added a NULL version of this file for classic 68K runtime (not
  45.                                     supported)
  46. */
  47.  
  48. #include "NavigationServicesSupport.h"
  49. #include <CodeFragments.h>
  50. #include <Finder.h>
  51. #include <Dialogs.h>
  52. #include <LowMem.h>
  53. //#include <string.h>
  54. #include <Processes.h>
  55.  
  56. extern Boolean gInModalState;
  57.  
  58.  
  59. static Handle NewOpenHandle(OSType applicationSignature, short numTypes, OSType typeList[])
  60. {
  61.     Handle hdl = NULL;
  62.     
  63.     if ( numTypes > 0 )
  64.     {
  65.     
  66.         hdl = NewHandle(sizeof(NavTypeList) + numTypes * sizeof(OSType));
  67.     
  68.         if ( hdl != NULL )
  69.         {
  70.             NavTypeListHandle open        = (NavTypeListHandle)hdl;
  71.             
  72.             (*open)->componentSignature = applicationSignature;
  73.             (*open)->osTypeCount        = numTypes;
  74.             BlockMoveData(typeList, (*open)->osType, numTypes * sizeof(OSType));
  75.         }
  76.     }
  77.     
  78.     return hdl;
  79. }
  80.  
  81.  
  82.  
  83.  
  84. static OSStatus SendOpenAE(AEDescList list)
  85. {
  86.     OSStatus        err;
  87.     AEAddressDesc    theAddress;
  88.     AppleEvent        dummyReply;
  89.     AppleEvent        theEvent;
  90.     
  91.     theAddress.descriptorType    = typeNull;
  92.     theAddress.dataHandle        = NULL;
  93.  
  94.     do {
  95.         ProcessSerialNumber psn;
  96.  
  97.         err = GetCurrentProcess(&psn);
  98.         if ( err != noErr) break;
  99.         
  100.         err =AECreateDesc(typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber), &theAddress);
  101.         if ( err != noErr) break;
  102.             
  103.         dummyReply.descriptorType    = typeNull;
  104.         dummyReply.dataHandle        = NULL;
  105.  
  106.         err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &theAddress, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  107.         if ( err != noErr) break;
  108.         
  109.         err = AEPutParamDesc(&theEvent, keyDirectObject, &list);
  110.         if ( err != noErr) break;
  111.         
  112.         err = AESend(&theEvent, &dummyReply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  113.         if ( err != noErr) break;
  114.         
  115.             
  116.     } while (false);
  117.     
  118.     return err;
  119. }
  120.  
  121.  
  122.  
  123. OSStatus OpenFileDialog(OSType applicationSignature, short numTypes, OSType typeList[], NavEventProcPtr eventProc, FSSpec* fileSpec, OSType* fileType)
  124. {
  125.     NavReplyRecord        theReply;
  126.     NavDialogOptions    dialogOptions;
  127.     OSErr                theErr        = noErr;
  128.     NavTypeListHandle    openList    = NULL;
  129.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  130.  
  131.     NavGetDefaultDialogOptions(&dialogOptions);
  132.  
  133.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  134.     
  135.     openList = (NavTypeListHandle)NewOpenHandle(applicationSignature, numTypes, typeList);
  136.     if ( openList )
  137.     {
  138.         HLock((Handle)openList);
  139.     }
  140.     
  141.     theErr = NavGetFile(NULL, &theReply, &dialogOptions, eventUPP, NULL, NULL, openList, NULL);
  142.     DisposeRoutineDescriptor(eventUPP);
  143.     
  144.     if (theReply.validRecord)
  145.     {
  146.         // grab the target FSSpec from the AEDesc for opening:    
  147.         AEDesc     resultDesc;
  148.         FInfo    fileInfo;
  149.  
  150.         // Is this a single file open
  151.         if ( fileSpec != NULL )
  152.         {
  153.             AEKeyword keyword;
  154.             
  155.             theErr = AEGetNthDesc(&theReply.selection, 1, typeFSS, &keyword, &resultDesc);
  156.             if (theErr == noErr) {
  157.                 theErr = AEGetDescData(&resultDesc,typeFSS,fileSpec,sizeof(FSSpec));
  158.             }
  159.                 
  160.             // decide if the doc we fileSpec opening is a PICT or TEXT
  161.             theErr = FSpGetFInfo(fileSpec, &fileInfo);
  162.             if (theErr == noErr)
  163.             {
  164.                 if ( fileType != NULL )
  165.                     *fileType = fileInfo.fdType;
  166.             }
  167.         }
  168.         else
  169.         {
  170.             // Multiple files open: use ApleEvents
  171.             theErr = SendOpenAE(theReply.selection);
  172.         }
  173.  
  174.         NavDisposeReply(&theReply);
  175.     }
  176.     else
  177.     {
  178.         theErr = userCanceledErr;
  179.     }
  180.  
  181.     if (openList != NULL)
  182.     {
  183.         HUnlock((Handle)openList);
  184.         DisposeHandle((Handle)openList);
  185.     }
  186.     
  187.     return theErr;
  188. }
  189.  
  190.  
  191. short ConfirmSaveDialog(StringPtr documentName, Boolean quitting, NavEventProcPtr eventProc)
  192. {
  193. //    OSStatus                theStatusErr     = noErr;
  194.     OSErr                     theErr             = noErr;
  195.     NavAskSaveChangesResult    reply             = 0;
  196.     NavAskSaveChangesAction    action             = 0;
  197.     NavEventUPP                eventUPP        = NewNavEventProc(eventProc);
  198.     NavDialogOptions        dialogOptions;
  199.     short                    result             = cancel;
  200.     
  201.     if (quitting)
  202.         action = kNavSaveChangesQuittingApplication;
  203.     else
  204.         action = kNavSaveChangesClosingDocument;
  205.         
  206.     BlockMoveData(LMGetCurApName(),dialogOptions.clientName,LMGetCurApName()[0]+1);
  207.     BlockMoveData(documentName,dialogOptions.savedFileName,documentName[0]+1);
  208.     
  209.     theErr = NavAskSaveChanges(    &dialogOptions,
  210.                                 action,
  211.                                 &reply,
  212.                                 eventUPP,
  213.                                 NULL);
  214.     DisposeRoutineDescriptor(eventUPP);
  215.     
  216.     // Map reply code to ok, cancel, dontSave
  217.     switch (reply)
  218.     {
  219.         case kNavAskSaveChangesSave:
  220.             result = ok;
  221.             break;
  222.             
  223.         case kNavAskSaveChangesCancel:
  224.             result = cancel;
  225.             break;
  226.             
  227.         case kNavAskSaveChangesDontSave:
  228.             result = dontSaveChanges;
  229.             break;
  230.     }
  231.     
  232.     return result;
  233. }
  234.  
  235.  
  236.  
  237. OSStatus SaveFileDialog(StringPtr fileName, OSType filetype, OSType fileCreator, 
  238.                         NavEventProcPtr eventProc, FSSpec* fileSpec, 
  239.                         Boolean* stationery, Boolean* replacing, NavReplyRecord* reply)
  240. {
  241.     NavDialogOptions    dialogOptions;
  242.     OSErr                theErr        = noErr;
  243.     NavEventUPP            eventUPP    = NewNavEventProc(eventProc);
  244.  
  245.     NavGetDefaultDialogOptions(&dialogOptions);
  246.  
  247.     dialogOptions.dialogOptionFlags |= (stationery != NULL ? kNavAllowStationery : 0);
  248.     BlockMoveData(fileName, dialogOptions.savedFileName, fileName[0] + 1);
  249.     BlockMoveData(LMGetCurApName(), dialogOptions.clientName, LMGetCurApName()[0] + 1);
  250.  
  251.     theErr = NavPutFile(NULL, reply, &dialogOptions, eventUPP, filetype, fileCreator, NULL);
  252.     DisposeRoutineDescriptor(eventUPP);
  253.     
  254.     if (reply->validRecord)
  255.     {
  256.         // User saved
  257.         AEDesc     resultDesc;
  258.         AEKeyword keyword;
  259.             
  260.         // retrieve the returned selection:
  261.         theErr = AEGetNthDesc(&reply->selection, 1, typeFSS, &keyword, &resultDesc);
  262.         if (theErr == noErr) {
  263.             theErr = AEGetDescData(&resultDesc,typeFSS,fileSpec,sizeof(FSSpec));
  264.         }
  265.  
  266.         if ( replacing != NULL )
  267.             *replacing = reply->replacing;
  268.         
  269.         if ( stationery != NULL )
  270.         {
  271.             *stationery    = reply->isStationery;
  272.         }
  273.     }
  274.     else
  275.     {
  276.         // User cancelled
  277.         if ( replacing != NULL )
  278.             *replacing = false;
  279.         
  280.         if ( stationery != NULL )
  281.             *stationery    = false;    
  282.  
  283.         theErr = userCanceledErr;
  284.     }
  285.     
  286.     return theErr;
  287. }
  288.  
  289.  
  290.  
  291. OSStatus CompleteSave(const FSSpec *theSpec, NavReplyRecord* reply)
  292. {
  293. #pragma unused(theSpec)
  294.     OSStatus theErr;
  295.     
  296.     if (reply->validRecord)
  297.     {
  298.         theErr = NavCompleteSave(reply, kNavTranslateInPlace);
  299.     }
  300.  
  301.     theErr = NavDisposeReply(reply);
  302.     
  303.     return theErr;
  304. }
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. //
  313. // Callback to handle events that occur while navigation dialogs are up but really should be handled by the application
  314. //
  315.  
  316. extern void HandleEvent(EventRecord * pEvent);
  317.  
  318.  
  319. pascal void MyEventProc(const NavEventCallbackMessage callBackSelector, 
  320.                         NavCBRecPtr callBackParms, 
  321.                         NavCallBackUserData callBackUD)
  322. // Callback to handle event passing betwwn the navigation dialogs and the applicatio
  323. {
  324. #pragma unused(callBackUD)
  325.     if ( callBackSelector == kNavCBEvent )
  326.         switch (callBackParms->eventData.eventDataParms.event->what)
  327.         {
  328.             case updateEvt:
  329.             case activateEvt:
  330.             
  331.                 // remember not to adjust our menus while inside modal dialogs
  332.                 gInModalState = true;
  333.                 HandleEvent(callBackParms->eventData.eventDataParms.event);
  334.                 gInModalState = false;
  335.                 break;
  336.         }
  337. }
  338.  
  339.